package org.iori.util.io;

import java.io.File;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;


/**
 * The ftp class provides the connect to the ftp server. On the connect status,
 * file can be put into server.
 *
 * @author zhang_jianbin
 * @history
 *         <p>
 *         2007-9-24 Created, Zhang Jianbin
 *
 */
public class Ftp {

	private String host;

	private String user;

	private String passwd;

	private FTPClient ftp = new FTPClient();

	/**
	 * Constructor method
	 *
	 * @param host
	 *            the host adrress
	 * @param user
	 *            the ftp user
	 * @param passwd
	 *            the password for the ftp user
	 */
	public Ftp(String host, String user, String passwd) {
		this.host = host;
		this.user = user;
		this.passwd = passwd;
	}

	/**
	 * Connects to the ftp sever
	 *
	 * @throws FtpConnectException
	 *             if can not conenct to the ftp server using the host, user and
	 *             password
	 */
	public void connect() throws FtpConnectException {
		try {
			ftp.connect(host);
			boolean result = ftp.login(user, passwd);
			if (!result) {
				throw new FtpConnectException(ftp.getReplyCode(),
						"Connect to server" + host + " user=" + user);
			}
		} catch (IOException e) {
			throw new FtpConnectException(ftp.getReplyCode(), e.getMessage());
		}
	}

	/**
	 * Connects to the ftp sever
	 *
	 * @throws FtpConnectException
	 *             if can not conenct to the ftp server using the host, user and
	 *             password
	 */
	public void connect(int timeout) throws FtpConnectException {
		try {
			ftp.setConnectTimeout(timeout);
			ftp.connect(host);
			boolean result = ftp.login(user, passwd);
			if (!result) {
				throw new FtpConnectException(ftp.getReplyCode(),
						"Connect to server" + host + " user=" + user);
			}
		} catch (IOException e) {
			throw new FtpConnectException(ftp.getReplyCode(), e.getMessage());
		}
	}

	/**
	 * Disconnects to the ftp server and release resource.
	 *
	 */
	public void disconnect() {
		try {
			ftp.logout();
			ftp.disconnect();
		} catch (IOException e) {
		}
		ftp = null;
	}

	/**
	 * Upload the file to the ftp server.
	 *
	 * @param sourceFilename
	 *            the local source filename
	 * @param serverDir
	 *            the file put into the server dir
	 * @param serverFilename
	 *            the filename on the ftp server used after finished the source
	 *            file upload
	 * @throws FtpTransferException
	 *             if error occurs when data transfer
	 */
	public void putFile(String sourceFilename, String serverDir,
			String serverFilename) throws FtpTransferException {
		try {
			if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
				throw new Exception("Change file type tp binary failure.");
			}

			ftp.enterLocalPassiveMode();

			if (!ftp.changeWorkingDirectory(serverDir)) {
				throw new Exception("Change ftp server working directory to "
						+ serverDir + " failure.");
			}

			InputStream is = new FileInputStream(new File(sourceFilename));
			String toFilename = serverDir;
			if (!serverDir.endsWith("/")) {
				toFilename += "/" + serverFilename;
			} else {
				toFilename += serverFilename;
			}

			String ext = "";
			String baseFilename = toFilename;
			int dotPos = toFilename.lastIndexOf(".");
			if (dotPos != -1) {
				ext = toFilename.substring(dotPos);
				baseFilename = toFilename.substring(0, dotPos);
			}

			if (!ftp.storeFile(baseFilename + ".temp", is)) {
				throw new Exception("ftp.storeFile not success.");
			}
			if (!ftp.rename(baseFilename + ".temp", baseFilename + ext)) {
				throw new Exception("ftp.rename not success.");
			}

			is.close();
		} catch (Exception e) {
			throw new FtpTransferException(ftp.getReplyCode(), e.getMessage());
		}
	}
	public String SiteCommand(String chmod, String zipname)
			throws FtpTransferException {
		try {

			boolean flag =ftp.sendSiteCommand(chmod + " " + zipname);
			return ftp.getReplyString();
		} catch (IOException e) {
			throw new FtpTransferException(ftp.getReplyCode(), e.getMessage());
		}
	}
}
